1 // SPDX-License-Identifier: GPL-2.0
13 static bool check_need_swap(int file_endian
)
16 u8
*check
= (u8
*)&data
;
20 host_endian
= ELFDATA2LSB
;
22 host_endian
= ELFDATA2MSB
;
24 return host_endian
!= file_endian
;
27 #define NOTE_ALIGN(sz) (((sz) + 3) & ~3)
29 #define NT_GNU_BUILD_ID 3
31 static int read_build_id(void *note_data
, size_t note_len
, void *bf
,
32 size_t size
, bool need_swap
)
42 while (ptr
< (note_data
+ note_len
)) {
44 size_t namesz
, descsz
;
48 nhdr
->n_namesz
= bswap_32(nhdr
->n_namesz
);
49 nhdr
->n_descsz
= bswap_32(nhdr
->n_descsz
);
50 nhdr
->n_type
= bswap_32(nhdr
->n_type
);
53 namesz
= NOTE_ALIGN(nhdr
->n_namesz
);
54 descsz
= NOTE_ALIGN(nhdr
->n_descsz
);
59 if (nhdr
->n_type
== NT_GNU_BUILD_ID
&&
60 nhdr
->n_namesz
== sizeof("GNU")) {
61 if (memcmp(name
, "GNU", sizeof("GNU")) == 0) {
62 size_t sz
= min(size
, descsz
);
64 memset(bf
+ sz
, 0, size
- sz
);
74 int filename__read_debuglink(const char *filename __maybe_unused
,
75 char *debuglink __maybe_unused
,
76 size_t size __maybe_unused
)
82 * Just try PT_NOTE header otherwise fails
84 int filename__read_build_id(const char *filename
, void *bf
, size_t size
)
88 bool need_swap
= false;
89 u8 e_ident
[EI_NIDENT
];
94 fp
= fopen(filename
, "r");
98 if (fread(e_ident
, sizeof(e_ident
), 1, fp
) != 1)
101 if (memcmp(e_ident
, ELFMAG
, SELFMAG
) ||
102 e_ident
[EI_VERSION
] != EV_CURRENT
)
105 need_swap
= check_need_swap(e_ident
[EI_DATA
]);
108 fseek(fp
, 0, SEEK_SET
);
110 if (e_ident
[EI_CLASS
] == ELFCLASS32
) {
114 if (fread(&ehdr
, sizeof(ehdr
), 1, fp
) != 1)
118 ehdr
.e_phoff
= bswap_32(ehdr
.e_phoff
);
119 ehdr
.e_phentsize
= bswap_16(ehdr
.e_phentsize
);
120 ehdr
.e_phnum
= bswap_16(ehdr
.e_phnum
);
123 buf_size
= ehdr
.e_phentsize
* ehdr
.e_phnum
;
124 buf
= malloc(buf_size
);
128 fseek(fp
, ehdr
.e_phoff
, SEEK_SET
);
129 if (fread(buf
, buf_size
, 1, fp
) != 1)
132 for (i
= 0, phdr
= buf
; i
< ehdr
.e_phnum
; i
++, phdr
++) {
137 phdr
->p_type
= bswap_32(phdr
->p_type
);
138 phdr
->p_offset
= bswap_32(phdr
->p_offset
);
139 phdr
->p_filesz
= bswap_32(phdr
->p_filesz
);
142 if (phdr
->p_type
!= PT_NOTE
)
145 buf_size
= phdr
->p_filesz
;
146 offset
= phdr
->p_offset
;
147 tmp
= realloc(buf
, buf_size
);
152 fseek(fp
, offset
, SEEK_SET
);
153 if (fread(buf
, buf_size
, 1, fp
) != 1)
156 ret
= read_build_id(buf
, buf_size
, bf
, size
, need_swap
);
165 if (fread(&ehdr
, sizeof(ehdr
), 1, fp
) != 1)
169 ehdr
.e_phoff
= bswap_64(ehdr
.e_phoff
);
170 ehdr
.e_phentsize
= bswap_16(ehdr
.e_phentsize
);
171 ehdr
.e_phnum
= bswap_16(ehdr
.e_phnum
);
174 buf_size
= ehdr
.e_phentsize
* ehdr
.e_phnum
;
175 buf
= malloc(buf_size
);
179 fseek(fp
, ehdr
.e_phoff
, SEEK_SET
);
180 if (fread(buf
, buf_size
, 1, fp
) != 1)
183 for (i
= 0, phdr
= buf
; i
< ehdr
.e_phnum
; i
++, phdr
++) {
188 phdr
->p_type
= bswap_32(phdr
->p_type
);
189 phdr
->p_offset
= bswap_64(phdr
->p_offset
);
190 phdr
->p_filesz
= bswap_64(phdr
->p_filesz
);
193 if (phdr
->p_type
!= PT_NOTE
)
196 buf_size
= phdr
->p_filesz
;
197 offset
= phdr
->p_offset
;
198 tmp
= realloc(buf
, buf_size
);
203 fseek(fp
, offset
, SEEK_SET
);
204 if (fread(buf
, buf_size
, 1, fp
) != 1)
207 ret
= read_build_id(buf
, buf_size
, bf
, size
, need_swap
);
220 int sysfs__read_build_id(const char *filename
, void *build_id
, size_t size
)
228 fd
= open(filename
, O_RDONLY
);
232 if (fstat(fd
, &stbuf
) < 0)
235 buf_size
= stbuf
.st_size
;
236 buf
= malloc(buf_size
);
240 if (read(fd
, buf
, buf_size
) != (ssize_t
) buf_size
)
243 ret
= read_build_id(buf
, buf_size
, build_id
, size
, false);
251 int symsrc__init(struct symsrc
*ss
, struct dso
*dso
, const char *name
,
252 enum dso_binary_type type
)
254 int fd
= open(name
, O_RDONLY
);
258 ss
->name
= strdup(name
);
269 dso
->load_errno
= errno
;
273 bool symsrc__possibly_runtime(struct symsrc
*ss __maybe_unused
)
275 /* Assume all sym sources could be a runtime image. */
279 bool symsrc__has_symtab(struct symsrc
*ss __maybe_unused
)
284 void symsrc__destroy(struct symsrc
*ss
)
290 int dso__synthesize_plt_symbols(struct dso
*dso __maybe_unused
,
291 struct symsrc
*ss __maybe_unused
)
296 static int fd__is_64_bit(int fd
)
298 u8 e_ident
[EI_NIDENT
];
300 if (lseek(fd
, 0, SEEK_SET
))
303 if (readn(fd
, e_ident
, sizeof(e_ident
)) != sizeof(e_ident
))
306 if (memcmp(e_ident
, ELFMAG
, SELFMAG
) ||
307 e_ident
[EI_VERSION
] != EV_CURRENT
)
310 return e_ident
[EI_CLASS
] == ELFCLASS64
;
313 enum dso_type
dso__type_fd(int fd
)
318 ret
= fd__is_64_bit(fd
);
320 return DSO__TYPE_UNKNOWN
;
323 return DSO__TYPE_64BIT
;
325 if (readn(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
326 return DSO__TYPE_UNKNOWN
;
328 if (ehdr
.e_machine
== EM_X86_64
)
329 return DSO__TYPE_X32BIT
;
331 return DSO__TYPE_32BIT
;
334 int dso__load_sym(struct dso
*dso
, struct map
*map __maybe_unused
,
336 struct symsrc
*runtime_ss __maybe_unused
,
337 int kmodule __maybe_unused
)
339 unsigned char build_id
[BUILD_ID_SIZE
];
342 ret
= fd__is_64_bit(ss
->fd
);
344 dso
->is_64_bit
= ret
;
346 if (filename__read_build_id(ss
->name
, build_id
, BUILD_ID_SIZE
) > 0) {
347 dso__set_build_id(dso
, build_id
);
352 int file__read_maps(int fd __maybe_unused
, bool exe __maybe_unused
,
353 mapfn_t mapfn __maybe_unused
, void *data __maybe_unused
,
354 bool *is_64_bit __maybe_unused
)
359 int kcore_extract__create(struct kcore_extract
*kce __maybe_unused
)
364 void kcore_extract__delete(struct kcore_extract
*kce __maybe_unused
)
368 int kcore_copy(const char *from_dir __maybe_unused
,
369 const char *to_dir __maybe_unused
)
374 void symbol__elf_init(void)
378 char *dso__demangle_sym(struct dso
*dso __maybe_unused
,
379 int kmodule __maybe_unused
,
380 const char *elf_name __maybe_unused
)