Initialize Tizen 2.3
[external/prelink.git] / src / stabs.c
1 /* Copyright (C) 2001, 2005, 2006 Red Hat, Inc.
2    Written by Jakub Jelinek <jakub@redhat.com>, 2001.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #include <config.h>
19 #include <assert.h>
20 #include <byteswap.h>
21 #include <endian.h>
22 #include <error.h>
23
24 #include "prelink.h"
25
26 #define N_ZERO          0x00
27 #define N_GSYM          0x20
28 #define N_FNAME         0x22
29 #define N_FUN           0x24
30 #define N_STSYM         0x26
31 #define N_LCSYM         0x28
32 #define N_MAIN          0x2a
33 #define N_BNSYM         0x2e
34 #define N_PC            0x30
35 #define N_NSYMS         0x32
36 #define N_NOMAP         0x34
37 #define N_OBJ           0x38
38 #define N_OPT           0x3c
39 #define N_RSYM          0x40
40 #define N_M2C           0x42
41 #define N_SLINE         0x44
42 #define N_DSLINE        0x46
43 #define N_BSLINE        0x48
44 #define N_BROWS         0x48
45 #define N_DEFD          0x4a
46 #define N_ENSYM         0x4e
47 #define N_EHDECL        0x50
48 #define N_MOD2          0x50
49 #define N_CATCH         0x54
50 #define N_SSYM          0x60
51 #define N_SO            0x64
52 #define N_LSYM          0x80
53 #define N_BINCL         0x82
54 #define N_SOL           0x84
55 #define N_PSYM          0xa0
56 #define N_EINCL         0xa2
57 #define N_ENTRY         0xa4
58 #define N_LBRAC         0xc0
59 #define N_EXCL          0xc2
60 #define N_SCOPE         0xc4
61 #define N_RBRAC         0xe0
62 #define N_BCOMM         0xe2
63 #define N_ECOMM         0xe4
64 #define N_ECOML         0xe8
65 #define N_LENG          0xfe
66
67 static uint32_t
68 read_native (char *p)
69 {
70   return *(uint32_t *)p;
71 }
72
73 static uint32_t
74 read_swap (char *p)
75 {
76   return bswap_32 (*(uint32_t *)p);
77 }
78
79 static void
80 write_native (char *p, uint32_t v)
81 {
82   *(uint32_t *)p = v;
83 }
84
85 static void
86 write_swap (char *p, uint32_t v)
87 {
88   *(uint32_t *)p = bswap_32 (v);
89 }
90
91 int
92 adjust_stabs (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust)
93 {
94   Elf_Data *data = NULL;
95   Elf_Scn *scn = dso->scn[n];
96   off_t off;
97   uint32_t (*read_32) (char *p);
98   void (*write_32) (char *p, uint32_t v);
99   uint32_t value;
100   int sec, type;
101
102   assert (dso->shdr[n].sh_entsize == 12);
103   data = elf_getdata (scn, NULL);
104   assert (data != NULL && data->d_buf != NULL);
105   assert (elf_getdata (scn, data) == NULL);
106   assert (data->d_off == 0 && data->d_size == dso->shdr[n].sh_size);
107 #if __BYTE_ORDER == __BIG_ENDIAN
108   if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
109 #elif __BYTE_ORDER == __LITTLE_ENDIAN
110   if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
111 #else
112 # error Not supported host endianess
113 #endif
114     {
115       read_32 = read_native;
116       write_32 = write_native;
117     }
118 #if __BYTE_ORDER == __BIG_ENDIAN
119   else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
120 #elif __BYTE_ORDER == __LITTLE_ENDIAN
121   else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
122 #endif
123     {
124       read_32 = read_swap;
125       write_32 = write_swap;
126     }
127   else
128     {
129       error (0, 0, "%s: Wrong ELF data enconding", dso->filename);
130       return 1;
131     }
132
133   for (off = 0; off < data->d_size; off += 12)
134     {
135     switch ((type = *(uint8_t *)(data->d_buf + off + 4)))
136       {
137       case N_FUN:
138         /* If string is "", N_FUN is function length, otherwise
139            it is function start address.  */
140         if (read_32 (data->d_buf + off) == 0)
141           break;
142         /* FALLTHROUGH */
143       case N_STSYM:
144       case N_LCSYM:
145       case N_CATCH:
146       case N_SO:
147       case N_SOL:
148       case N_BNSYM:
149       case N_ENSYM:
150         value = read_32 (data->d_buf + off + 8);
151         sec = addr_to_sec (dso, value);
152         if (sec != -1)
153           {
154             addr_adjust (value, start, adjust);
155             write_32 (data->d_buf + off + 8, value);
156           }
157         break;
158       /* These should be always 0.  */
159       case N_GSYM:
160       case N_BINCL:
161       case N_EINCL:
162       case N_EXCL:
163       case N_BCOMM:
164       case N_ECOMM:
165       /* These contain other values.  */
166       case N_ZERO:
167       case N_NSYMS:
168       case N_NOMAP:
169       case N_RSYM:
170       case N_LSYM:
171       case N_PSYM:
172       case N_OPT:
173       /* These are relative.  */
174       case N_LBRAC:
175       case N_RBRAC:
176       case N_SLINE:
177       case N_BSLINE:
178       case N_DSLINE:
179         break;
180       default:
181         error (0, 0, "%s: Unknown stabs code 0x%02x\n", dso->filename, type);
182         return 1;
183       }
184     }
185
186   elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY);
187   return 0;
188 }