Skip to content

Commit 72f7058

Browse files
committed
readelf: decode flag bits in DT_FLAGS/DT_FLAGS_1
Decode d_val when the tag is DT_FLAGS or DT_FLAGS_1 based on the information at: https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-42444.html Submitted by Bora Ozarslan <[email protected]>, with subsequent refactoring by me. Obtained from: FreeBSD r343592, r343593, r343665, r345646
1 parent f3db9ac commit 72f7058

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

readelf/readelf.c

+65
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ struct mips_option {
211211
const char *desc;
212212
};
213213

214+
struct flag_desc {
215+
uint64_t flag;
216+
const char *desc;
217+
};
218+
214219
static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op,
215220
int t);
216221
static const char *aeabi_adv_simd_arch(uint64_t simd);
@@ -284,6 +289,7 @@ static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die,
284289
static void dump_dwarf_str(struct readelf *re);
285290
static void dump_eflags(struct readelf *re, uint64_t e_flags);
286291
static void dump_elf(struct readelf *re);
292+
static void dump_flags(struct flag_desc *fd, uint64_t flags);
287293
static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab);
288294
static void dump_dynamic(struct readelf *re);
289295
static void dump_liblist(struct readelf *re);
@@ -2713,6 +2719,59 @@ dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn)
27132719
}
27142720
}
27152721

2722+
static void
2723+
dump_flags(struct flag_desc *desc, uint64_t val)
2724+
{
2725+
struct flag_desc *fd;
2726+
2727+
for (fd = desc; fd->flag != 0; fd++) {
2728+
if (val & fd->flag) {
2729+
val &= ~fd->flag;
2730+
printf(" %s", fd->desc);
2731+
}
2732+
}
2733+
if (val != 0)
2734+
printf(" unknown (0x%jx)", (uintmax_t)val);
2735+
printf("\n");
2736+
}
2737+
2738+
static struct flag_desc dt_flags[] = {
2739+
{ DF_ORIGIN, "ORIGIN" },
2740+
{ DF_SYMBOLIC, "SYMBOLIC" },
2741+
{ DF_TEXTREL, "TEXTREL" },
2742+
{ DF_BIND_NOW, "BIND_NOW" },
2743+
{ DF_STATIC_TLS, "STATIC_TLS" },
2744+
{ 0, NULL }
2745+
};
2746+
2747+
static struct flag_desc dt_flags_1[] = {
2748+
{ DF_1_BIND_NOW, "NOW" },
2749+
{ DF_1_GLOBAL, "GLOBAL" },
2750+
{ 0x4, "GROUP" },
2751+
{ DF_1_NODELETE, "NODELETE" },
2752+
{ DF_1_LOADFLTR, "LOADFLTR" },
2753+
{ 0x20, "INITFIRST" },
2754+
{ DF_1_NOOPEN, "NOOPEN" },
2755+
{ DF_1_ORIGIN, "ORIGIN" },
2756+
{ 0x100, "DIRECT" },
2757+
{ DF_1_INTERPOSE, "INTERPOSE" },
2758+
{ DF_1_NODEFLIB, "NODEFLIB" },
2759+
{ 0x1000, "NODUMP" },
2760+
{ 0x2000, "CONFALT" },
2761+
{ 0x4000, "ENDFILTEE" },
2762+
{ 0x8000, "DISPRELDNE" },
2763+
{ 0x10000, "DISPRELPND" },
2764+
{ 0x20000, "NODIRECT" },
2765+
{ 0x40000, "IGNMULDEF" },
2766+
{ 0x80000, "NOKSYMS" },
2767+
{ 0x100000, "NOHDR" },
2768+
{ 0x200000, "EDITED" },
2769+
{ 0x400000, "NORELOC" },
2770+
{ 0x800000, "SYMINTPOSE" },
2771+
{ 0x1000000, "GLOBAUDIT" },
2772+
{ 0, NULL }
2773+
};
2774+
27162775
static void
27172776
dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
27182777
{
@@ -2796,6 +2855,12 @@ dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab)
27962855
case DT_GNU_PRELINKED:
27972856
printf(" %s\n", timestamp(dyn->d_un.d_val));
27982857
break;
2858+
case DT_FLAGS:
2859+
dump_flags(dt_flags, dyn->d_un.d_val);
2860+
break;
2861+
case DT_FLAGS_1:
2862+
dump_flags(dt_flags_1, dyn->d_un.d_val);
2863+
break;
27992864
default:
28002865
printf("\n");
28012866
}

0 commit comments

Comments
 (0)