1/*
2 * Copyright (c) 1999-2004 University of New South Wales
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#pragma once
8
9#include <types.h>
10
11#define ELF32_R_TYPE(val)		((val) & 0xff)
12#define R_ARM_NONE		0	/* No reloc */
13#define R_ARM_RELATIVE		23	/* Adjust by program base */
14/*
15 * File header
16 */
17struct Elf32_Header {
18    unsigned char   e_ident[16];
19    uint16_t        e_type;	/* Relocatable=1, Executable=2 (+ some
20				 * more ..) */
21    uint16_t        e_machine;	/* Target architecture: MIPS=8 */
22    uint32_t        e_version;	/* Elf version (should be 1) */
23    uint32_t        e_entry;	/* Code entry point */
24    uint32_t        e_phoff;	/* Program header table */
25    uint32_t        e_shoff;	/* Section header table */
26    uint32_t        e_flags;	/* Flags */
27    uint16_t        e_ehsize;	/* ELF header size */
28    uint16_t        e_phentsize;	/* Size of one program segment
29					 * header */
30    uint16_t        e_phnum;	/* Number of program segment
31					 * headers */
32    uint16_t        e_shentsize;	/* Size of one section header */
33    uint16_t        e_shnum;	/* Number of section headers */
34    uint16_t        e_shstrndx;	/* Section header index of the
35					 * string table for section header
36					 * * names */
37};
38
39/*
40 * Section header
41 */
42struct Elf32_Shdr {
43    uint32_t        sh_name;
44    uint32_t        sh_type;
45    uint32_t        sh_flags;
46    uint32_t        sh_addr;
47    uint32_t        sh_offset;
48    uint32_t        sh_size;
49    uint32_t        sh_link;
50    uint32_t        sh_info;
51    uint32_t        sh_addralign;
52    uint32_t        sh_entsize;
53};
54
55/*
56 * Program header
57 */
58struct Elf32_Phdr {
59    uint32_t p_type;	/* Segment type: Loadable segment = 1 */
60    uint32_t p_offset;	/* Offset of segment in file */
61    uint32_t p_vaddr;	/* Reqd virtual address of segment
62					 * when loading */
63    uint32_t p_paddr;	/* Reqd physical address of
64					 * segment (ignore) */
65    uint32_t p_filesz;	/* How many bytes this segment
66					 * occupies in file */
67    uint32_t p_memsz;	/* How many bytes this segment
68					 * should occupy in * memory (when
69					 * * loading, expand the segment
70					 * by * concatenating enough zero
71					 * bytes to it) */
72    uint32_t p_flags;	/* Flags: logical "or" of PF_
73					 * constants below */
74    uint32_t p_align;	/* Reqd alignment of segment in
75					 * memory */
76};
77
78/*
79 * Dynamic header
80 */
81struct Elf32_Dyn
82{
83  uint32_t d_tag;			/* Dynamic entry type */
84  union
85    {
86      uint32_t d_val;			/* Integer value */
87      uint32_t d_ptr;			/* Address value */
88    } d_un;
89};
90
91
92/*
93 * Relocation
94 */
95struct Elf32_Rel
96{
97  uint32_t r_offset;		/* Address */
98  uint32_t r_info;			/* Relocation type and symbol index */
99};
100
101
102int elf32_checkFile(struct Elf32_Header *file);
103struct Elf32_Phdr * elf32_getProgramSegmentTable(struct Elf32_Header *file);
104unsigned elf32_getNumSections(struct Elf32_Header *file);
105char * elf32_getStringTable(struct Elf32_Header *file);
106char * elf32_getSegmentStringTable(struct Elf32_Header *file);
107
108static inline struct Elf32_Shdr *
109elf32_getSectionTable(struct Elf32_Header *file) {
110    /* Cast heaven! */
111    return (struct Elf32_Shdr*) (uintptr_t) (((uintptr_t) file) + file->e_shoff);
112}
113
114/* accessor functions */
115static inline uint32_t
116elf32_getSectionType(struct Elf32_Header *file, uint16_t s)
117{
118    return elf32_getSectionTable(file)[s].sh_type;
119}
120
121static inline uint32_t
122elf32_getSectionFlags(struct Elf32_Header *file, uint16_t s)
123{
124    return elf32_getSectionTable(file)[s].sh_flags;
125}
126
127char * elf32_getSectionName(struct Elf32_Header *file, int i);
128uint32_t elf32_getSectionSize(struct Elf32_Header *file, int i);
129uint32_t elf32_getSectionAddr(struct Elf32_Header *elfFile, int i);
130void * elf32_getSection(struct Elf32_Header *file, int i);
131void * elf32_getSectionNamed(struct Elf32_Header *file, char *str);
132int elf32_getSegmentType (struct Elf32_Header *file, int segment);
133void elf32_getSegmentInfo(struct Elf32_Header *file, int segment, uint64_t *p_vaddr,
134                          uint64_t *p_paddr, uint64_t *p_filesz,
135                          uint64_t *p_offset, uint64_t *p_memsz);
136uint32_t elf32_getEntryPoint (struct Elf32_Header *file);
137
138/* Program header functions */
139uint16_t elf32_getNumProgramHeaders(struct Elf32_Header *file);
140
141static inline struct Elf32_Phdr *
142elf32_getProgramHeaderTable(struct Elf32_Header *file) {
143    /* Cast heaven! */
144    return (struct Elf32_Phdr*) (uintptr_t) (((uintptr_t) file) + file->e_phoff);
145}
146
147/* accessor functions */
148static inline uint32_t
149elf32_getProgramHeaderFlags(struct Elf32_Header *file, uint16_t ph)
150{
151    return elf32_getProgramHeaderTable(file)[ph].p_flags;
152}
153
154static inline uint32_t
155elf32_getProgramHeaderType(struct Elf32_Header *file, uint16_t ph)
156{
157    return elf32_getProgramHeaderTable(file)[ph].p_type;
158}
159
160static inline uint32_t
161elf32_getProgramHeaderFileSize(struct Elf32_Header *file, uint16_t ph)
162{
163    return elf32_getProgramHeaderTable(file)[ph].p_filesz;
164}
165
166static inline uint32_t
167elf32_getProgramHeaderMemorySize(struct Elf32_Header *file, uint16_t ph)
168{
169    return elf32_getProgramHeaderTable(file)[ph].p_memsz;
170}
171
172static inline uint32_t
173elf32_getProgramHeaderVaddr(struct Elf32_Header *file, uint16_t ph)
174{
175    return elf32_getProgramHeaderTable(file)[ph].p_vaddr;
176}
177
178static inline uint32_t
179elf32_getProgramHeaderPaddr(struct Elf32_Header *file, uint16_t ph)
180{
181    return elf32_getProgramHeaderTable(file)[ph].p_paddr;
182}
183
184static inline uint32_t
185elf32_getProgramHeaderOffset(struct Elf32_Header *file, uint16_t ph)
186{
187    return elf32_getProgramHeaderTable(file)[ph].p_offset;
188}
189
190