1*a9fa9459Szrj /* BFD back-end for verilog hex memory dump files.
2*a9fa9459Szrj Copyright (C) 2009-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj Written by Anthony Green <green@moxielogic.com>
4*a9fa9459Szrj
5*a9fa9459Szrj This file is part of BFD, the Binary File Descriptor library.
6*a9fa9459Szrj
7*a9fa9459Szrj This program is free software; you can redistribute it and/or modify
8*a9fa9459Szrj it under the terms of the GNU General Public License as published by
9*a9fa9459Szrj the Free Software Foundation; either version 3 of the License, or
10*a9fa9459Szrj (at your option) any later version.
11*a9fa9459Szrj
12*a9fa9459Szrj This program is distributed in the hope that it will be useful,
13*a9fa9459Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
14*a9fa9459Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*a9fa9459Szrj GNU General Public License for more details.
16*a9fa9459Szrj
17*a9fa9459Szrj You should have received a copy of the GNU General Public License
18*a9fa9459Szrj along with this program; if not, write to the Free Software
19*a9fa9459Szrj Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20*a9fa9459Szrj MA 02110-1301, USA. */
21*a9fa9459Szrj
22*a9fa9459Szrj
23*a9fa9459Szrj /* SUBSECTION
24*a9fa9459Szrj Verilog hex memory file handling
25*a9fa9459Szrj
26*a9fa9459Szrj DESCRIPTION
27*a9fa9459Szrj
28*a9fa9459Szrj Verilog hex memory files cannot hold anything but addresses
29*a9fa9459Szrj and data, so that's all that we implement.
30*a9fa9459Szrj
31*a9fa9459Szrj The syntax of the text file is described in the IEEE standard
32*a9fa9459Szrj for Verilog. Briefly, the file contains two types of tokens:
33*a9fa9459Szrj data and optional addresses. The tokens are separated by
34*a9fa9459Szrj whitespace and comments. Comments may be single line or
35*a9fa9459Szrj multiline, using syntax similar to C++. Addresses are
36*a9fa9459Szrj specified by a leading "at" character (@) and are always
37*a9fa9459Szrj hexadecimal strings. Data and addresses may contain
38*a9fa9459Szrj underscore (_) characters.
39*a9fa9459Szrj
40*a9fa9459Szrj If no address is specified, the data is assumed to start at
41*a9fa9459Szrj address 0. Similarly, if data exists before the first
42*a9fa9459Szrj specified address, then that data is assumed to start at
43*a9fa9459Szrj address 0.
44*a9fa9459Szrj
45*a9fa9459Szrj
46*a9fa9459Szrj EXAMPLE
47*a9fa9459Szrj @1000
48*a9fa9459Szrj 01 ae 3f 45 12
49*a9fa9459Szrj
50*a9fa9459Szrj DESCRIPTION
51*a9fa9459Szrj @1000 specifies the starting address for the memory data.
52*a9fa9459Szrj The following characters describe the 5 bytes at 0x1000. */
53*a9fa9459Szrj
54*a9fa9459Szrj
55*a9fa9459Szrj #include "sysdep.h"
56*a9fa9459Szrj #include "bfd.h"
57*a9fa9459Szrj #include "libbfd.h"
58*a9fa9459Szrj #include "libiberty.h"
59*a9fa9459Szrj #include "safe-ctype.h"
60*a9fa9459Szrj
61*a9fa9459Szrj /* Macros for converting between hex and binary. */
62*a9fa9459Szrj
63*a9fa9459Szrj static const char digs[] = "0123456789ABCDEF";
64*a9fa9459Szrj
65*a9fa9459Szrj #define NIBBLE(x) hex_value(x)
66*a9fa9459Szrj #define HEX(buffer) ((NIBBLE ((buffer)[0])<<4) + NIBBLE ((buffer)[1]))
67*a9fa9459Szrj #define TOHEX(d, x) \
68*a9fa9459Szrj d[1] = digs[(x) & 0xf]; \
69*a9fa9459Szrj d[0] = digs[((x) >> 4) & 0xf];
70*a9fa9459Szrj
71*a9fa9459Szrj /* When writing a verilog memory dump file, we write them in the order
72*a9fa9459Szrj in which they appear in memory. This structure is used to hold them
73*a9fa9459Szrj in memory. */
74*a9fa9459Szrj
75*a9fa9459Szrj struct verilog_data_list_struct
76*a9fa9459Szrj {
77*a9fa9459Szrj struct verilog_data_list_struct *next;
78*a9fa9459Szrj bfd_byte * data;
79*a9fa9459Szrj bfd_vma where;
80*a9fa9459Szrj bfd_size_type size;
81*a9fa9459Szrj };
82*a9fa9459Szrj
83*a9fa9459Szrj typedef struct verilog_data_list_struct verilog_data_list_type;
84*a9fa9459Szrj
85*a9fa9459Szrj /* The verilog tdata information. */
86*a9fa9459Szrj
87*a9fa9459Szrj typedef struct verilog_data_struct
88*a9fa9459Szrj {
89*a9fa9459Szrj verilog_data_list_type *head;
90*a9fa9459Szrj verilog_data_list_type *tail;
91*a9fa9459Szrj }
92*a9fa9459Szrj tdata_type;
93*a9fa9459Szrj
94*a9fa9459Szrj static bfd_boolean
verilog_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long mach)95*a9fa9459Szrj verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach)
96*a9fa9459Szrj {
97*a9fa9459Szrj if (arch != bfd_arch_unknown)
98*a9fa9459Szrj return bfd_default_set_arch_mach (abfd, arch, mach);
99*a9fa9459Szrj
100*a9fa9459Szrj abfd->arch_info = & bfd_default_arch_struct;
101*a9fa9459Szrj return TRUE;
102*a9fa9459Szrj }
103*a9fa9459Szrj
104*a9fa9459Szrj /* We have to save up all the outpu for a splurge before output. */
105*a9fa9459Szrj
106*a9fa9459Szrj static bfd_boolean
verilog_set_section_contents(bfd * abfd,sec_ptr section,const void * location,file_ptr offset,bfd_size_type bytes_to_do)107*a9fa9459Szrj verilog_set_section_contents (bfd *abfd,
108*a9fa9459Szrj sec_ptr section,
109*a9fa9459Szrj const void * location,
110*a9fa9459Szrj file_ptr offset,
111*a9fa9459Szrj bfd_size_type bytes_to_do)
112*a9fa9459Szrj {
113*a9fa9459Szrj tdata_type *tdata = abfd->tdata.verilog_data;
114*a9fa9459Szrj verilog_data_list_type *entry;
115*a9fa9459Szrj
116*a9fa9459Szrj entry = (verilog_data_list_type *) bfd_alloc (abfd, sizeof (* entry));
117*a9fa9459Szrj if (entry == NULL)
118*a9fa9459Szrj return FALSE;
119*a9fa9459Szrj
120*a9fa9459Szrj if (bytes_to_do
121*a9fa9459Szrj && (section->flags & SEC_ALLOC)
122*a9fa9459Szrj && (section->flags & SEC_LOAD))
123*a9fa9459Szrj {
124*a9fa9459Szrj bfd_byte *data;
125*a9fa9459Szrj
126*a9fa9459Szrj data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
127*a9fa9459Szrj if (data == NULL)
128*a9fa9459Szrj return FALSE;
129*a9fa9459Szrj memcpy ((void *) data, location, (size_t) bytes_to_do);
130*a9fa9459Szrj
131*a9fa9459Szrj entry->data = data;
132*a9fa9459Szrj entry->where = section->lma + offset;
133*a9fa9459Szrj entry->size = bytes_to_do;
134*a9fa9459Szrj
135*a9fa9459Szrj /* Sort the records by address. Optimize for the common case of
136*a9fa9459Szrj adding a record to the end of the list. */
137*a9fa9459Szrj if (tdata->tail != NULL
138*a9fa9459Szrj && entry->where >= tdata->tail->where)
139*a9fa9459Szrj {
140*a9fa9459Szrj tdata->tail->next = entry;
141*a9fa9459Szrj entry->next = NULL;
142*a9fa9459Szrj tdata->tail = entry;
143*a9fa9459Szrj }
144*a9fa9459Szrj else
145*a9fa9459Szrj {
146*a9fa9459Szrj verilog_data_list_type **look;
147*a9fa9459Szrj
148*a9fa9459Szrj for (look = &tdata->head;
149*a9fa9459Szrj *look != NULL && (*look)->where < entry->where;
150*a9fa9459Szrj look = &(*look)->next)
151*a9fa9459Szrj ;
152*a9fa9459Szrj entry->next = *look;
153*a9fa9459Szrj *look = entry;
154*a9fa9459Szrj if (entry->next == NULL)
155*a9fa9459Szrj tdata->tail = entry;
156*a9fa9459Szrj }
157*a9fa9459Szrj }
158*a9fa9459Szrj return TRUE;
159*a9fa9459Szrj }
160*a9fa9459Szrj
161*a9fa9459Szrj static bfd_boolean
verilog_write_address(bfd * abfd,bfd_vma address)162*a9fa9459Szrj verilog_write_address (bfd *abfd, bfd_vma address)
163*a9fa9459Szrj {
164*a9fa9459Szrj char buffer[12];
165*a9fa9459Szrj char *dst = buffer;
166*a9fa9459Szrj bfd_size_type wrlen;
167*a9fa9459Szrj
168*a9fa9459Szrj /* Write the address. */
169*a9fa9459Szrj *dst++ = '@';
170*a9fa9459Szrj TOHEX (dst, (address >> 24));
171*a9fa9459Szrj dst += 2;
172*a9fa9459Szrj TOHEX (dst, (address >> 16));
173*a9fa9459Szrj dst += 2;
174*a9fa9459Szrj TOHEX (dst, (address >> 8));
175*a9fa9459Szrj dst += 2;
176*a9fa9459Szrj TOHEX (dst, (address));
177*a9fa9459Szrj dst += 2;
178*a9fa9459Szrj *dst++ = '\r';
179*a9fa9459Szrj *dst++ = '\n';
180*a9fa9459Szrj wrlen = dst - buffer;
181*a9fa9459Szrj
182*a9fa9459Szrj return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen;
183*a9fa9459Szrj }
184*a9fa9459Szrj
185*a9fa9459Szrj /* Write a record of type, of the supplied number of bytes. The
186*a9fa9459Szrj supplied bytes and length don't have a checksum. That's worked out
187*a9fa9459Szrj here. */
188*a9fa9459Szrj
189*a9fa9459Szrj static bfd_boolean
verilog_write_record(bfd * abfd,const bfd_byte * data,const bfd_byte * end)190*a9fa9459Szrj verilog_write_record (bfd *abfd,
191*a9fa9459Szrj const bfd_byte *data,
192*a9fa9459Szrj const bfd_byte *end)
193*a9fa9459Szrj {
194*a9fa9459Szrj char buffer[50];
195*a9fa9459Szrj const bfd_byte *src = data;
196*a9fa9459Szrj char *dst = buffer;
197*a9fa9459Szrj bfd_size_type wrlen;
198*a9fa9459Szrj
199*a9fa9459Szrj /* Write the data. */
200*a9fa9459Szrj for (src = data; src < end; src++)
201*a9fa9459Szrj {
202*a9fa9459Szrj TOHEX (dst, *src);
203*a9fa9459Szrj dst += 2;
204*a9fa9459Szrj *dst++ = ' ';
205*a9fa9459Szrj }
206*a9fa9459Szrj *dst++ = '\r';
207*a9fa9459Szrj *dst++ = '\n';
208*a9fa9459Szrj wrlen = dst - buffer;
209*a9fa9459Szrj
210*a9fa9459Szrj return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen;
211*a9fa9459Szrj }
212*a9fa9459Szrj
213*a9fa9459Szrj static bfd_boolean
verilog_write_section(bfd * abfd,tdata_type * tdata ATTRIBUTE_UNUSED,verilog_data_list_type * list)214*a9fa9459Szrj verilog_write_section (bfd *abfd,
215*a9fa9459Szrj tdata_type *tdata ATTRIBUTE_UNUSED,
216*a9fa9459Szrj verilog_data_list_type *list)
217*a9fa9459Szrj {
218*a9fa9459Szrj unsigned int octets_written = 0;
219*a9fa9459Szrj bfd_byte *location = list->data;
220*a9fa9459Szrj
221*a9fa9459Szrj verilog_write_address (abfd, list->where);
222*a9fa9459Szrj while (octets_written < list->size)
223*a9fa9459Szrj {
224*a9fa9459Szrj unsigned int octets_this_chunk = list->size - octets_written;
225*a9fa9459Szrj
226*a9fa9459Szrj if (octets_this_chunk > 16)
227*a9fa9459Szrj octets_this_chunk = 16;
228*a9fa9459Szrj
229*a9fa9459Szrj if (! verilog_write_record (abfd,
230*a9fa9459Szrj location,
231*a9fa9459Szrj location + octets_this_chunk))
232*a9fa9459Szrj return FALSE;
233*a9fa9459Szrj
234*a9fa9459Szrj octets_written += octets_this_chunk;
235*a9fa9459Szrj location += octets_this_chunk;
236*a9fa9459Szrj }
237*a9fa9459Szrj
238*a9fa9459Szrj return TRUE;
239*a9fa9459Szrj }
240*a9fa9459Szrj
241*a9fa9459Szrj static bfd_boolean
verilog_write_object_contents(bfd * abfd)242*a9fa9459Szrj verilog_write_object_contents (bfd *abfd)
243*a9fa9459Szrj {
244*a9fa9459Szrj tdata_type *tdata = abfd->tdata.verilog_data;
245*a9fa9459Szrj verilog_data_list_type *list;
246*a9fa9459Szrj
247*a9fa9459Szrj /* Now wander though all the sections provided and output them. */
248*a9fa9459Szrj list = tdata->head;
249*a9fa9459Szrj
250*a9fa9459Szrj while (list != (verilog_data_list_type *) NULL)
251*a9fa9459Szrj {
252*a9fa9459Szrj if (! verilog_write_section (abfd, tdata, list))
253*a9fa9459Szrj return FALSE;
254*a9fa9459Szrj list = list->next;
255*a9fa9459Szrj }
256*a9fa9459Szrj return TRUE;
257*a9fa9459Szrj }
258*a9fa9459Szrj
259*a9fa9459Szrj /* Initialize by filling in the hex conversion array. */
260*a9fa9459Szrj
261*a9fa9459Szrj static void
verilog_init(void)262*a9fa9459Szrj verilog_init (void)
263*a9fa9459Szrj {
264*a9fa9459Szrj static bfd_boolean inited = FALSE;
265*a9fa9459Szrj
266*a9fa9459Szrj if (! inited)
267*a9fa9459Szrj {
268*a9fa9459Szrj inited = TRUE;
269*a9fa9459Szrj hex_init ();
270*a9fa9459Szrj }
271*a9fa9459Szrj }
272*a9fa9459Szrj
273*a9fa9459Szrj /* Set up the verilog tdata information. */
274*a9fa9459Szrj
275*a9fa9459Szrj static bfd_boolean
verilog_mkobject(bfd * abfd)276*a9fa9459Szrj verilog_mkobject (bfd *abfd)
277*a9fa9459Szrj {
278*a9fa9459Szrj tdata_type *tdata;
279*a9fa9459Szrj
280*a9fa9459Szrj verilog_init ();
281*a9fa9459Szrj
282*a9fa9459Szrj tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
283*a9fa9459Szrj if (tdata == NULL)
284*a9fa9459Szrj return FALSE;
285*a9fa9459Szrj
286*a9fa9459Szrj abfd->tdata.verilog_data = tdata;
287*a9fa9459Szrj tdata->head = NULL;
288*a9fa9459Szrj tdata->tail = NULL;
289*a9fa9459Szrj
290*a9fa9459Szrj return TRUE;
291*a9fa9459Szrj }
292*a9fa9459Szrj
293*a9fa9459Szrj #define verilog_close_and_cleanup _bfd_generic_close_and_cleanup
294*a9fa9459Szrj #define verilog_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
295*a9fa9459Szrj #define verilog_new_section_hook _bfd_generic_new_section_hook
296*a9fa9459Szrj #define verilog_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
297*a9fa9459Szrj #define verilog_bfd_is_local_label_name bfd_generic_is_local_label_name
298*a9fa9459Szrj #define verilog_get_lineno _bfd_nosymbols_get_lineno
299*a9fa9459Szrj #define verilog_find_nearest_line _bfd_nosymbols_find_nearest_line
300*a9fa9459Szrj #define verilog_find_inliner_info _bfd_nosymbols_find_inliner_info
301*a9fa9459Szrj #define verilog_make_empty_symbol _bfd_generic_make_empty_symbol
302*a9fa9459Szrj #define verilog_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
303*a9fa9459Szrj #define verilog_read_minisymbols _bfd_generic_read_minisymbols
304*a9fa9459Szrj #define verilog_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
305*a9fa9459Szrj #define verilog_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
306*a9fa9459Szrj #define verilog_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
307*a9fa9459Szrj #define verilog_bfd_relax_section bfd_generic_relax_section
308*a9fa9459Szrj #define verilog_bfd_gc_sections bfd_generic_gc_sections
309*a9fa9459Szrj #define verilog_bfd_merge_sections bfd_generic_merge_sections
310*a9fa9459Szrj #define verilog_bfd_is_group_section bfd_generic_is_group_section
311*a9fa9459Szrj #define verilog_bfd_discard_group bfd_generic_discard_group
312*a9fa9459Szrj #define verilog_section_already_linked _bfd_generic_section_already_linked
313*a9fa9459Szrj #define verilog_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
314*a9fa9459Szrj #define verilog_bfd_link_add_symbols _bfd_generic_link_add_symbols
315*a9fa9459Szrj #define verilog_bfd_link_just_syms _bfd_generic_link_just_syms
316*a9fa9459Szrj #define verilog_bfd_final_link _bfd_generic_final_link
317*a9fa9459Szrj #define verilog_bfd_link_split_section _bfd_generic_link_split_section
318*a9fa9459Szrj
319*a9fa9459Szrj const bfd_target verilog_vec =
320*a9fa9459Szrj {
321*a9fa9459Szrj "verilog", /* Name. */
322*a9fa9459Szrj bfd_target_verilog_flavour,
323*a9fa9459Szrj BFD_ENDIAN_UNKNOWN, /* Target byte order. */
324*a9fa9459Szrj BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
325*a9fa9459Szrj (HAS_RELOC | EXEC_P | /* Object flags. */
326*a9fa9459Szrj HAS_LINENO | HAS_DEBUG |
327*a9fa9459Szrj HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
328*a9fa9459Szrj (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
329*a9fa9459Szrj | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
330*a9fa9459Szrj 0, /* Leading underscore. */
331*a9fa9459Szrj ' ', /* AR_pad_char. */
332*a9fa9459Szrj 16, /* AR_max_namelen. */
333*a9fa9459Szrj 0, /* match priority. */
334*a9fa9459Szrj bfd_getb64, bfd_getb_signed_64, bfd_putb64,
335*a9fa9459Szrj bfd_getb32, bfd_getb_signed_32, bfd_putb32,
336*a9fa9459Szrj bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
337*a9fa9459Szrj bfd_getb64, bfd_getb_signed_64, bfd_putb64,
338*a9fa9459Szrj bfd_getb32, bfd_getb_signed_32, bfd_putb32,
339*a9fa9459Szrj bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Hdrs. */
340*a9fa9459Szrj
341*a9fa9459Szrj {
342*a9fa9459Szrj _bfd_dummy_target,
343*a9fa9459Szrj _bfd_dummy_target,
344*a9fa9459Szrj _bfd_dummy_target,
345*a9fa9459Szrj _bfd_dummy_target,
346*a9fa9459Szrj },
347*a9fa9459Szrj {
348*a9fa9459Szrj bfd_false,
349*a9fa9459Szrj verilog_mkobject,
350*a9fa9459Szrj bfd_false,
351*a9fa9459Szrj bfd_false,
352*a9fa9459Szrj },
353*a9fa9459Szrj { /* bfd_write_contents. */
354*a9fa9459Szrj bfd_false,
355*a9fa9459Szrj verilog_write_object_contents,
356*a9fa9459Szrj bfd_false,
357*a9fa9459Szrj bfd_false,
358*a9fa9459Szrj },
359*a9fa9459Szrj
360*a9fa9459Szrj BFD_JUMP_TABLE_GENERIC (_bfd_generic),
361*a9fa9459Szrj BFD_JUMP_TABLE_COPY (_bfd_generic),
362*a9fa9459Szrj BFD_JUMP_TABLE_CORE (_bfd_nocore),
363*a9fa9459Szrj BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
364*a9fa9459Szrj BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
365*a9fa9459Szrj BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
366*a9fa9459Szrj BFD_JUMP_TABLE_WRITE (verilog),
367*a9fa9459Szrj BFD_JUMP_TABLE_LINK (_bfd_nolink),
368*a9fa9459Szrj BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
369*a9fa9459Szrj
370*a9fa9459Szrj NULL,
371*a9fa9459Szrj
372*a9fa9459Szrj NULL
373*a9fa9459Szrj };
374