@Override
	protected DataTypeComponent[] getAllComponents(MemBuffer buf) {

		try {
			ByteProvider provider = new MemBufferByteProvider(buf);
			BinaryReader reader = new BinaryReader(provider, false);

			ArrayList<DataTypeComponent> list = new ArrayList<>();

			LEB128Info sleb128 = reader.readNext(LEB128Info::signed);
			long groupSize = sleb128.asLong();
			list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
				list.size(), "group_size", null));

			sleb128 = reader.readNext(LEB128Info::signed);
			long groupFlags = sleb128.asLong();
			list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
				list.size(), "group_flags", null));

			boolean groupedByInfo = (groupFlags & RELOCATION_GROUPED_BY_INFO_FLAG) != 0;
			boolean groupedByDelta = (groupFlags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) != 0;
			boolean groupedByAddend = (groupFlags & RELOCATION_GROUPED_BY_ADDEND_FLAG) != 0;
			boolean groupHasAddend = (groupFlags & RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0;

			long groupOffsetDelta = 0;
			if (groupedByDelta) {
				sleb128 = reader.readNext(LEB128Info::signed);
				groupOffsetDelta = sleb128.asLong();

				long minOffset = baseRelocOffset + groupOffsetDelta;
				String rangeStr = "First relocation offset: 0x" + Long.toHexString(minOffset);

				list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
					list.size(), "group_offsetDelta", rangeStr));
			}

			if (groupedByInfo) {
				sleb128 = reader.readNext(LEB128Info::signed);
				list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
					list.size(), "group_info", null));
			}

			if (groupedByAddend && groupHasAddend) {
				sleb128 = reader.readNext(LEB128Info::signed);
				list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
					list.size(), "group_addend", null));
			}

			long relocOffset = baseRelocOffset;

			if (groupedByDelta && groupedByInfo && (!groupHasAddend || groupedByAddend)) {
				// no individual relocation entry data
				relocOffset += (groupSize - 1) * groupOffsetDelta;
			}
			else {
				for (int i = 0; i < groupSize; i++) {
					if (groupedByDelta) {
						relocOffset += groupOffsetDelta;
					}
					else {
						sleb128 = reader.readNext(LEB128Info::signed);
						long baseOffset = relocOffset;
						relocOffset += sleb128.asLong();
						DataTypeComponent dtc = new ReadOnlyDataTypeComponent(
							new AndroidElfRelocationOffset(dataMgr, baseOffset, relocOffset), this,
							sleb128.getLength(), list.size(), (int) sleb128.getOffset(),
							"reloc_offset_" + i, null);
						list.add(dtc);
					}

					if (!groupedByInfo) {
						sleb128 = reader.readNext(LEB128Info::signed);
						list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
							list.size(), "reloc_info_" + i, null, relocOffset));
					}

					if (groupHasAddend && !groupedByAddend) {
						sleb128 = reader.readNext(LEB128Info::signed);
						list.add(AndroidElfRelocationTableDataType.getLEB128Component(sleb128, this,
							list.size(), "reloc_addend_" + i, null, relocOffset));
					}
				}
			}

			DataTypeComponent[] comps = new DataTypeComponent[list.size()];
			return list.toArray(comps);
		}
		catch (IOException e) {
			return null;
		}
	}
<code>AndroidElfRelocationGroup</code> provides a dynamic substructure 
component for relocation groups within a packed Android ELF Relocation Table.
See {@link AndroidElfRelocationTableDataType}.
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/AndroidElfRelocationGroup.java