[2/4] Add function for partitioning/splitting a section table
Commit Message
gdb/ChangeLog:
* exec.h, exec.c (split_section_table): New function.
Change-Id: I8909174aed892727bdd6d704cfe43763ee8969c3
---
gdb/exec.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/exec.h | 13 +++++++++++++
2 files changed, 68 insertions(+)
@@ -604,6 +604,61 @@ resize_section_table (struct target_section_table *table, int adjustment)
return old_count;
}
+/* See exec.h. */
+
+void
+split_section_table (struct target_section_table *orig,
+ struct target_section_table *splits,
+ bool (*criterion) (struct target_section *))
+{
+ int count = 0;
+
+ for (struct target_section *sect = orig->sections;
+ sect < orig->sections_end;
+ sect++)
+ {
+ if (criterion (sect))
+ count++;
+ }
+
+ /* Handle the case of an empty SPLITS table. */
+ if (count == 0)
+ {
+ splits->sections = nullptr;
+ splits->sections_end = nullptr;
+ return;
+ }
+
+ /* Handle case of an empty ORIG table. */
+ if (count == orig->sections_end - orig->sections)
+ {
+ splits = orig;
+ orig->sections = nullptr;
+ orig->sections_end = nullptr;
+ return;
+ }
+
+ /* Okay, we actually have something to do. Allocate a new table for
+ SPLITS. We'll resize ORIG after copying. */
+
+ splits->sections = XNEWVEC (struct target_section, count);
+ splits->sections_end = splits->sections + count;
+
+ for (struct target_section *sect = orig->sections,
+ *osect = sect,
+ *ssect = splits->sections;
+ sect < orig->sections_end;
+ sect++)
+ {
+ if (criterion (sect))
+ *ssect++ = *sect;
+ else
+ *osect++ = *sect;
+ }
+
+ resize_section_table (orig, -count);
+}
+
/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
Returns 0 if OK, 1 on error. */
@@ -44,6 +44,19 @@ extern int build_section_table (struct bfd *, struct target_section **,
extern void clear_section_table (struct target_section_table *table);
+/* Split a target section table ORIG into two parts. Sections meeting
+ CRITERION will be placed into SPLITS. The original table ORIG will
+ be adjusted and resized as necessary, removing those sections which
+ were placed into SPLITS. If no sections in ORIG satisfy CRITERION,
+ sections and sections_end in SPLITS will be set to nullptr,
+ representing an empty table. Likewise, if all sections in ORIG
+ satisfy CRITERION, ORIG will be set to an empty table and SPLITS
+ end up with all of the sections originally in ORIG. */
+
+extern void split_section_table (struct target_section_table *orig,
+ struct target_section_table *splits,
+ bool (*criterion) (struct target_section *));
+
/* The current inferior is a child vforked and its program space is
shared with its parent. This pushes the exec target on the
current/child inferior's target stack if there are sections in the