mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
libdrgn: use strswitch for ELF section names
Move the definitions of the section names to a Python script, gen_elf_sections.py, and use that to generate the enum definitions and a lookup function. This is preparation for checking for section names with the .dwo suffix in the future. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
93cd8ee0b3
commit
02e344a7dd
@ -26,7 +26,9 @@ STRSWITCH_INCS = drgn_program_parse_vmcoreinfo.inc \
|
||||
BUILT_SOURCES = $(ARCH_DEFS_INCS) \
|
||||
$(STRSWITCH_INCS) \
|
||||
c_keywords.inc \
|
||||
drgn.h
|
||||
drgn.h \
|
||||
drgn_section_name_to_index.inc \
|
||||
elf_sections.h
|
||||
|
||||
noinst_LTLIBRARIES = libdrgnimpl.la
|
||||
|
||||
@ -47,12 +49,14 @@ libdrgnimpl_la_SOURCES = $(ARCH_DEFS_PYS:_defs.py=.c) \
|
||||
cityhash.h \
|
||||
debug_info.c \
|
||||
debug_info.h \
|
||||
drgn_section_name_to_index.inc \
|
||||
dwarf_constants.c \
|
||||
dwarf_constants.h \
|
||||
dwarf_info.c \
|
||||
dwarf_info.h \
|
||||
elf_file.c \
|
||||
elf_file.h \
|
||||
elf_sections.h \
|
||||
error.c \
|
||||
error.h \
|
||||
hash_table.c \
|
||||
@ -131,6 +135,12 @@ drgn.h: drgn.h.in configure.ac
|
||||
-e 's/@DRGN_VERSION_PATCH@/$(word 3,$(subst ., ,@PACKAGE_VERSION@))/g' \
|
||||
$< > $@
|
||||
|
||||
drgn_section_name_to_index.inc: build-aux/gen_elf_sections.py build-aux/gen_strswitch.py build-aux/codegen_utils.py
|
||||
$(AM_V_GEN)$(PYTHON) $< | $(PYTHON) $(word 2, $^) -o $@ -
|
||||
|
||||
elf_sections.h: build-aux/gen_elf_sections.py build-aux/codegen_utils.py
|
||||
$(AM_V_GEN)$(PYTHON) $< -H > $@
|
||||
|
||||
lib_LTLIBRARIES = libdrgn.la
|
||||
|
||||
libdrgn_la_SOURCES =
|
||||
@ -191,6 +201,7 @@ EXTRA_DIST = $(ARCH_DEFS_PYS) \
|
||||
build-aux/gen_arch_inc_strswitch.py \
|
||||
build-aux/gen_c_keywords_inc_strswitch.py \
|
||||
build-aux/gen_constants.py \
|
||||
build-aux/gen_elf_sections.py \
|
||||
build-aux/gen_strswitch.py \
|
||||
drgn.h.in
|
||||
|
||||
|
1
libdrgn/build-aux/.gitignore
vendored
1
libdrgn/build-aux/.gitignore
vendored
@ -4,4 +4,5 @@
|
||||
!/gen_arch_inc_strswitch.py
|
||||
!/gen_c_keywords_inc_strswitch.py
|
||||
!/gen_constants.py
|
||||
!/gen_elf_sections.py
|
||||
!/gen_strswitch.py
|
||||
|
136
libdrgn/build-aux/gen_elf_sections.py
Executable file
136
libdrgn/build-aux/gen_elf_sections.py
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import sys
|
||||
from typing import TextIO
|
||||
|
||||
from codegen_utils import c_string_literal
|
||||
|
||||
DWARF_INDEX_SECTIONS = (
|
||||
".debug_info",
|
||||
".debug_types",
|
||||
".debug_abbrev",
|
||||
".debug_str",
|
||||
".debug_str_offsets",
|
||||
".debug_line",
|
||||
".debug_line_str",
|
||||
)
|
||||
|
||||
CACHED_SECTIONS = (
|
||||
".debug_addr",
|
||||
".debug_frame",
|
||||
".eh_frame",
|
||||
".orc_unwind_ip",
|
||||
".orc_unwind",
|
||||
".debug_loc",
|
||||
".debug_loclists",
|
||||
)
|
||||
|
||||
UNCACHED_SECTIONS = (
|
||||
".text",
|
||||
".got",
|
||||
)
|
||||
|
||||
|
||||
def section_enumerator_name(section_name: str) -> str:
|
||||
return "DRGN_SCN_" + section_name.lstrip(".").upper()
|
||||
|
||||
|
||||
def gen_elf_sections_h(out_file: TextIO) -> None:
|
||||
out_file.write(
|
||||
"""\
|
||||
/* Generated by libdrgn/build-aux/gen_elf_sections.py -H. */
|
||||
|
||||
#ifndef DRGN_ELF_SECTIONS_H
|
||||
#define DRGN_ELF_SECTIONS_H
|
||||
|
||||
/**
|
||||
* Identifiers for important ELF sections so that they can be referenced by
|
||||
* index rather than name.
|
||||
*/
|
||||
enum drgn_section_index {
|
||||
"""
|
||||
)
|
||||
for section_name in DWARF_INDEX_SECTIONS:
|
||||
out_file.write(f"\t{section_enumerator_name(section_name)},\n")
|
||||
out_file.write(
|
||||
"""\
|
||||
/** Indices less than this are cached when the module is loaded. */
|
||||
DRGN_SECTION_INDEX_NUM_PRECACHE,
|
||||
"""
|
||||
)
|
||||
|
||||
for i, section_name in enumerate(CACHED_SECTIONS):
|
||||
if i == 0:
|
||||
out_file.write(
|
||||
f"\t{section_enumerator_name(section_name)} = DRGN_SECTION_INDEX_NUM_PRECACHE,\n"
|
||||
)
|
||||
else:
|
||||
out_file.write(f"\t{section_enumerator_name(section_name)},\n")
|
||||
out_file.write(
|
||||
"""\
|
||||
/** Indices less than this may have their data cached. */
|
||||
DRGN_SECTION_INDEX_NUM_DATA,
|
||||
"""
|
||||
)
|
||||
|
||||
for i, section_name in enumerate(UNCACHED_SECTIONS):
|
||||
if i == 0:
|
||||
out_file.write(
|
||||
f"\t{section_enumerator_name(section_name)} = DRGN_SECTION_INDEX_NUM_DATA,\n"
|
||||
)
|
||||
else:
|
||||
out_file.write(f"\t{section_enumerator_name(section_name)},\n")
|
||||
out_file.write(
|
||||
"""\
|
||||
/** Number of section indices. */
|
||||
DRGN_SECTION_INDEX_NUM
|
||||
};
|
||||
|
||||
#endif /* DRGN_ELF_SECTIONS_H */
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def gen_drgn_section_name_to_index_inc_strswitch(out_file: TextIO) -> None:
|
||||
out_file.write("/* Generated by libdrgn/build-aux/gen_elf_sections.py. */\n")
|
||||
out_file.write(
|
||||
"""\
|
||||
static enum drgn_section_index drgn_section_name_to_index(const char *name)
|
||||
{
|
||||
@strswitch (name)@
|
||||
"""
|
||||
)
|
||||
for section_name in itertools.chain(
|
||||
DWARF_INDEX_SECTIONS, CACHED_SECTIONS, UNCACHED_SECTIONS
|
||||
):
|
||||
out_file.write(f"\t@case {c_string_literal(section_name)}@\n")
|
||||
out_file.write(f"\t\treturn {section_enumerator_name(section_name)};\n")
|
||||
out_file.write(
|
||||
"""\
|
||||
@default@
|
||||
return DRGN_SECTION_INDEX_NUM;
|
||||
@endswitch@
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--header", "-H", action="store_true", help="generate header file"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.header:
|
||||
gen_elf_sections_h(sys.stdout)
|
||||
else:
|
||||
gen_drgn_section_name_to_index_inc_strswitch(sys.stdout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -23,24 +23,7 @@ struct drgn_error *read_elf_section(Elf_Scn *scn, Elf_Data **ret)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char * const drgn_section_index_names[] = {
|
||||
[DRGN_SCN_DEBUG_INFO] = ".debug_info",
|
||||
[DRGN_SCN_DEBUG_TYPES] = ".debug_types",
|
||||
[DRGN_SCN_DEBUG_ABBREV] = ".debug_abbrev",
|
||||
[DRGN_SCN_DEBUG_STR] = ".debug_str",
|
||||
[DRGN_SCN_DEBUG_STR_OFFSETS] = ".debug_str_offsets",
|
||||
[DRGN_SCN_DEBUG_LINE] = ".debug_line",
|
||||
[DRGN_SCN_DEBUG_LINE_STR] = ".debug_line_str",
|
||||
[DRGN_SCN_DEBUG_ADDR] = ".debug_addr",
|
||||
[DRGN_SCN_DEBUG_FRAME] = ".debug_frame",
|
||||
[DRGN_SCN_EH_FRAME] = ".eh_frame",
|
||||
[DRGN_SCN_ORC_UNWIND_IP] = ".orc_unwind_ip",
|
||||
[DRGN_SCN_ORC_UNWIND] = ".orc_unwind",
|
||||
[DRGN_SCN_DEBUG_LOC] = ".debug_loc",
|
||||
[DRGN_SCN_DEBUG_LOCLISTS] = ".debug_loclists",
|
||||
[DRGN_SCN_TEXT] = ".text",
|
||||
[DRGN_SCN_GOT] = ".got",
|
||||
};
|
||||
#include "drgn_section_name_to_index.inc"
|
||||
|
||||
struct drgn_error *drgn_elf_file_create(struct drgn_module *module,
|
||||
const char *path, Elf *elf,
|
||||
@ -78,13 +61,10 @@ struct drgn_error *drgn_elf_file_create(struct drgn_module *module,
|
||||
err = drgn_error_libelf();
|
||||
goto err;
|
||||
}
|
||||
for (size_t i = 0; i < DRGN_SECTION_INDEX_NUM; i++) {
|
||||
if (!file->scns[i] &&
|
||||
strcmp(scnname, drgn_section_index_names[i]) == 0) {
|
||||
file->scns[i] = scn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enum drgn_section_index index =
|
||||
drgn_section_name_to_index(scnname);
|
||||
if (index < DRGN_SECTION_INDEX_NUM && !file->scns[index])
|
||||
file->scns[index] = scn;
|
||||
}
|
||||
*ret = file;
|
||||
return NULL;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <libelf.h>
|
||||
|
||||
#include "binary_buffer.h"
|
||||
#include "elf_sections.h" // IWYU pragma: export
|
||||
#include "platform.h"
|
||||
|
||||
struct drgn_module;
|
||||
@ -39,40 +40,6 @@ struct drgn_module;
|
||||
*/
|
||||
struct drgn_error *read_elf_section(Elf_Scn *scn, Elf_Data **ret);
|
||||
|
||||
/**
|
||||
* Identifiers for important ELF sections so that they can be referenced by
|
||||
* index rather than name.
|
||||
*/
|
||||
enum drgn_section_index {
|
||||
DRGN_SCN_DEBUG_INFO,
|
||||
DRGN_SCN_DEBUG_TYPES,
|
||||
DRGN_SCN_DEBUG_ABBREV,
|
||||
DRGN_SCN_DEBUG_STR,
|
||||
DRGN_SCN_DEBUG_STR_OFFSETS,
|
||||
DRGN_SCN_DEBUG_LINE,
|
||||
DRGN_SCN_DEBUG_LINE_STR,
|
||||
|
||||
/** Indices less than this are cached when the module is loaded. */
|
||||
DRGN_SECTION_INDEX_NUM_PRECACHE,
|
||||
|
||||
DRGN_SCN_DEBUG_ADDR = DRGN_SECTION_INDEX_NUM_PRECACHE,
|
||||
DRGN_SCN_DEBUG_FRAME,
|
||||
DRGN_SCN_EH_FRAME,
|
||||
DRGN_SCN_ORC_UNWIND_IP,
|
||||
DRGN_SCN_ORC_UNWIND,
|
||||
DRGN_SCN_DEBUG_LOC,
|
||||
DRGN_SCN_DEBUG_LOCLISTS,
|
||||
|
||||
/** Indices less than this may have their data cached. */
|
||||
DRGN_SECTION_INDEX_NUM_DATA,
|
||||
|
||||
DRGN_SCN_TEXT = DRGN_SECTION_INDEX_NUM_DATA,
|
||||
DRGN_SCN_GOT,
|
||||
|
||||
/** Number of section indices. */
|
||||
DRGN_SECTION_INDEX_NUM,
|
||||
};
|
||||
|
||||
/** An ELF file used by a @ref drgn_module. */
|
||||
struct drgn_elf_file {
|
||||
/** Module using this file. */
|
||||
|
Loading…
Reference in New Issue
Block a user