* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: dbgrif.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)dbgrif.c 1.15 06/03/06 SMI"
/* FIXME: Currently this debugger interface is designed solely
* for supporting GDB. I have tried to make it as general
* as possible, but no doubt interface differences will remain
* Ultimately, this interface will split into 2. A set of
* general interaction stubs will exist, and they
* will support loadable modules which inturn can be customised
* for each available debugger required.
/* #include <sys/conf.h> */
#include <string.h> /* for memset in FD_ZERO */
#define MAX_PORT_STEP 10 /* DEFAULT_PORT to DEFAULT_PORT+9 */
/* allow upto 5 pending connections will never get that many */
#define MAX_CONNECTIONS 5
int port_offset_number
; /* for more than one debugger */
bool_t flag_remdeb_if
= false;
DS_unattached
, DS_stopped
, DS_running
* available for the sim to tell the debugger about a
* ... something else to do eventually
typedef struct DEBUGGER
{
/* ID who we are attached to - if anything */
domain_t
* domainp
; /* so we can read memory etc. */
/* NOTE: have to go via CPU anyway if caches modeled*/
config_proc_t
* config_procp
; /* config proc */
void * pspecp
; /* within that proc */
/* communication buffers */
pthread_mutex_t stop_lock
;
Sim_Mem_Read_Failed_No_Mem
,
Sim_Mem_Write_Failed_No_Mem
,
Sim_Mem_Clear_Failed_No_Mem
,
PD(Dbgr_Clear_Breakpoint
)
PD(Sim_Breakpoint_Cleared
)
PD(Sim_Mem_Read_Failed_No_Mem
)
PD(Sim_Mem_Write_Failed_No_Mem
)
PD(Sim_Mem_Clear_Failed_No_Mem
)
#define MAX_BUF_SIZE 8192
static int do_recv(int skt
, uint8_t * ptr
, int expect
);
static protocol_t
recv_buffer(debugger_t
* dbgp
, int * nrecvdp
);
static int send_buffer(debugger_t
* dbgrp
, protocol_t cmd
, int num
);
static uint16_t get_uint16(uint8_t * bp
);
static void put_uint16(uint8_t * bp
, uint16_t val
);
static uint32_t get_uint32(uint8_t * bp
);
static void put_uint32(uint8_t * bp
, uint32_t val
);
static uint64_t get_uint64(uint8_t * bp
);
static void put_uint64(uint8_t * bp
, uint64_t val
);
*--------------------------------------------
* Register re-map name table
* Get from the GDB numbering to the simulator
* ... for the moment this is for SPARC only
* but will eventually fix this ...
*--------------------------------------------
static char * gdb_reg_name
[] = {
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", /*values 0-31*/
"o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", /* 32-63 */
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
"f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", /* 64-79 */
"f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
/* Mapping for the GDB register numbering to the CPU models numbering */
static void if_exec_start(debugger_t
* dbgrp
);
static void if_exec_wait(debugger_t
* dbgrp
);
static uint64_t symtab_base
;
static char * symtab_fname
;
static void if_write_register(debugger_t
* dbgrp
);
static void if_read_register(debugger_t
* dbgrp
);
static void if_clear_breakpoint(debugger_t
* dbgrp
);
static void if_set_breakpoint(debugger_t
* dbgrp
);
static void if_read_memory(debugger_t
* dbgrp
);
static void if_write_memory(debugger_t
* dbgrp
);
static void if_clear_memory(debugger_t
* dbgrp
);
#define DBGRD(s) do { s } while (0)
#define DBGRD(s) do { } while (0)
* Gah this builds a map from the GDB register numbers to
* those of the sparc processor being simulated ..
* .. based on the map exported for the given
* processor type. This should be done a better way,
* but this works for now : FIXME
void init_gdb_reg_map(reg_map_t
* reg_mapp
)
/* for each GDB name, find and map the number the
* cpu core model expects to see
for (count
=0; gdb_reg_name
[count
]!=(char*)0; count
++) ;
gdb_reg_map
= Xcalloc(count
, int);
for (idx
=0; idx
<count
; idx
++) {
matchp
= gdb_reg_name
[idx
];
/* brute force search for name */
for (j
=0; reg_mapp
[j
].namep
!= (char*)0; j
++) {
if (streq(reg_mapp
[j
].namep
, matchp
)) break;
/* shouldnt have gdb names we dont know ! */
assert(reg_mapp
[j
].namep
!= (char*)0);
gdb_reg_map
[idx
] = reg_mapp
[j
].idx
;
static void dbgrif_stop_cb(void *arg
)
debugger_t
*dbgrp
= (debugger_t
*)arg
;
DBGRD(printf("dbgrif_stop_cb()\n"););
dbgrp
->state
= DS_stopped
;
pthread_mutex_lock(&dbgrp
->stop_lock
);
pthread_cond_broadcast(&dbgrp
->stop_cv
);
pthread_mutex_unlock(&dbgrp
->stop_lock
);
* This new thread is invoked once contact with a debugger is
* been established. This thread exits once that debugger
* Any one debugger can stop the simulation, all are required
* to be active to continue simulation.
void * dbgrif(void * argp
)
debugger_t
* dbgrp
= (debugger_t
*)argp
;
* We have a potential contact, however we must
* setup the structures used for communication
dbgrp
->recv_buffer_p
= (uint8_t*)valloc(MAX_BUF_SIZE
);
if (dbgrp
->recv_buffer_p
== (uint8_t*)0) fatal("allocating recv buffer");
dbgrp
->send_buffer_p
= (uint8_t*)valloc(MAX_BUF_SIZE
);
if (dbgrp
->send_buffer_p
== (uint8_t*)0) fatal("allocating send buffer");
dbgrp
->recv_ptr
= dbgrp
->recv_buffer_p
+ 3;
dbgrp
->send_ptr
= dbgrp
->send_buffer_p
+ 3;
* Veryify the protocols match ...
* .... by exchanging the max protocol value
* Really should use some version checksum ... FIXME
res
= recv_buffer( dbgrp
, &length
);
send_buffer( dbgrp
, Dbgr_Protocol_Count
, 0 ); /* send regardless - will make other side fail too */
if (res
!=Dbgr_Protocol_Count
|| length
!=0) {
printf("Connection failed : received %d %d - debugger protocols do not match\n", res
, length
);
* OK we've established contact with a legitimate debugger
* run the command interface until we get the
* command to termnate this session
protocol_t cmd
= (protocol_t
)recv_buffer(dbgrp
, &recv_len
);
if (cmd
== Receive_error
) {
perror("failed in communication");
DBGRD( for (res
= 0; protodebug
[res
].cmd
!=-1 && protodebug
[res
].cmd
!=cmd
; res
++) ;
printf("command [%d] : %s\n",(int)cmd
,
protodebug
[res
].cmd
!= -1 ? protodebug
[res
].name
: "illegal value"); );
dbgrp
->recv_ptr
[recv_len
] = '\0';
DBGRD( printf("recvd: %s\n", dbgrp
->recv_ptr
); );
exec_cmds ( (char*)dbgrp
->recv_ptr
, cmd_ptr
);
send_buffer(dbgrp
, Sim_Command_Str_OK
, 0);
/* FIXME: for now the simulator must be in virgin state */
assert( dbgrp
->state
== DS_unattached
);
/* Make sure simulator is stopped and ready for attach */
/* FIXME: for now this is not compatible with the auto start mode */
assert( !options
.flag_auto_start
);
stop_cmd((char*)0, dbgrp
->cmd_ptr
); /* FIXME: prob. wrong too */
wait_for_simulation_stop(dbgrp
->cmd_ptr
);
if (cpu
[0] == (void*)0) {
printf( "Looks like you forgot to init the architecture (file blazerc) before\n"
"you did the sttach - try again\n");
send_buffer(dbgrp
->socket
, Sim_Attach_Failed
, 0);
dbgrp
->exec_state
= Exec_unattached
; /* sanity */
send_buffer(dbgrp
->socket
, Sim_Attach_OK
, 0);
dbgrp
->exec_state
= Exec_stopped
;
/* Kludge an attach just to get something
sysp
= LIST_ENTRY( target_config
.systems
, 0 );
dbgrp
->domainp
= LIST_ENTRY(sysp
->domains
, 0 );
dbgrp
->config_procp
= LIST_ENTRY(dbgrp
->domainp
->procs
, 0);
dbgrp
->pspecp
= dbgrp
->config_procp
->proc_typep
->dbgr_attach(dbgrp
->domainp
, dbgrp
->config_procp
, "0:0");
ASSERT(dbgrp
->config_procp
->proc_typep
->proc_magic
== CPU_MAGIC
);
init_gdb_reg_map(dbgrp
->config_procp
->proc_typep
->reg_mapp
); /* FIXME */
if (dbgrp
->pspecp
== NULL
) {
send_buffer(dbgrp
, Sim_Attach_Failed
, 0);
dbgrp
->state
= DS_stopped
;
send_buffer(dbgrp
, Sim_Attach_OK
, 0);
if_write_register(dbgrp
);
case Dbgr_Set_Breakpoint
:
if_set_breakpoint(dbgrp
);
case Dbgr_Clear_Breakpoint
:
if_clear_breakpoint(dbgrp
);
/* Cannot get here ... */
fatal("Dbgr_ReqStop unexpectedly received");
for (res
= 0; protodebug
[res
].cmd
!= -1 && protodebug
[res
].cmd
!= cmd
; res
++) ;
warning("unexpected command [%d] : %s\n",(int)cmd
,
protodebug
[res
].cmd
!= -1 ? protodebug
[res
].name
: "illegal value");
warning("unexpected command %d\n",(int)cmd
);
Xfree( dbgrp
->recv_buffer_p
);
Xfree( dbgrp
->send_buffer_p
);
* Clean up this debuggers session ...
* ... remove any assigned breakpoints etc ...
* Clean up debugger session count ?
return (void*)0; /* compiler joy */
* If a symtab message is pending build the response packet
* and send it back to the debugger
* The buffer format is quite simple:
* uint16 offset_to_filename { from buffer start }
* uint16 number_of_sections
* uint16 offset_to_section_name { from buffer start }
* uint64 section_load_vaddr
* .. until the end of the buffer.
* (each string is null terminated)
static void if_send_symtab_info(debugger_t
* dbgrp
)
sfp
= (sym_file_t
*)dbgrp
->sym_filep
;
/* First size the initial sections block */
stridx
= secidx
+ SEC_SIZE
*(sfp
->num_pos
);
/* copy in the map name */
/* and the number of sections */
put_uint16( dbgrp
->send_ptr
, stridx
);
put_uint16( dbgrp
->send_ptr
+2, sfp
->num_pos
);
len
= strlen( sfp
->mapnamep
);
strcpy( (char*)dbgrp
->send_ptr
+ stridx
, sfp
->mapnamep
);
for (i
=0; i
<sfp
->num_pos
; i
++) {
put_uint16( dbgrp
->send_ptr
+ secidx
, stridx
);
put_uint64( dbgrp
->send_ptr
+ secidx
+ 2, sfp
->pos
[i
].address
);
len
= strlen( sfp
->pos
[i
].namep
);
strcpy( (char*)dbgrp
->send_ptr
+ stridx
, sfp
->pos
[i
].namep
);
DBGRD( printf("\tif_exec_wait: returning Sim_SimTab_Load (%s)...\n", sfp
->mapnamep
););
send_buffer(dbgrp
->socket
, Sim_SimTab_Load
, stridx
);
symfile_cleanup(&dbgrp
->sym_filep
);
* Start execution again ...
* ... this is non-blocking (use if_exec_wait to wait until stopped)
static void if_exec_start(debugger_t
* dbgrp
)
DBGRD( printf("run!\n"););
dbgrp
->state
= DS_running
;
send_buffer(dbgrp
, Sim_Executing
, 0);
* Wait for execution to stop, and give the appropriate response
* ... if execution stopepd to load a symbol table signal that back
* ... after which the debugger should initiate a new run request.
static void if_exec_wait(debugger_t
* dbgrp
)
DBGRD( printf("wait until stopped...\n"););
pthread_mutex_lock(&dbgrp
->stop_lock
);
while (dbgrp
->state
!= DS_stopped
) {
pthread_cond_wait(&dbgrp
->stop_cv
, &dbgrp
->stop_lock
);
pthread_mutex_unlock(&dbgrp
->stop_lock
);
DBGRD( printf("\tif_exec_wait: returning Sim_Stopped ...\n"););
send_buffer(dbgrp
, Sim_Stopped
, 0);
static void if_read_register(debugger_t
* dbgrp
)
regno
= (dbgrp
->recv_ptr
[0]<<8) | dbgrp
->recv_ptr
[1];
if (!dbgrp
->config_procp
->proc_typep
->regread(dbgrp
->pspecp
, gdb_reg_map
[regno
], &val
)) {
warning("Register %d [%s] fetch failed", regno
, gdb_reg_name
[regno
]);
send_buffer( dbgrp
, Sim_Reg_Value_Rtnd
, 0);
DBGRD( printf("read register %d : %s = 0x%llx\n",regno
,gdb_reg_name
[regno
],val
););
put_uint64(dbgrp
->send_ptr
, val
);
send_buffer( dbgrp
, Sim_Reg_Value_Rtnd
, 8);
static void if_write_register(debugger_t
* dbgrp
)
regno
= (dbgrp
->recv_ptr
[0]<<8) | dbgrp
->recv_ptr
[1];
val
= get_uint64(dbgrp
->recv_ptr
+ 2);
DBGRD( printf("write register %d : %s = 0x%llx\n",regno
,gdb_reg_name
[regno
],val
););
if (!dbgrp
->config_procp
->proc_typep
->regwrite(dbgrp
->pspecp
, gdb_reg_map
[regno
], val
)) {
warning("Register %d [%s] write failed", regno
, gdb_reg_name
[regno
]);
send_buffer( dbgrp
, Sim_Reg_Written
, 0);
static void if_set_breakpoint(debugger_t
* dbgrp
)
val
= get_uint64(dbgrp
->recv_ptr
);
DBGRD( printf("set breakpoint @ 0x%llx\n",val
););
dbgrp
->config_procp
->proc_typep
->dbgr_set_break(dbgrp
->pspecp
, val
);
send_buffer( dbgrp
, Sim_Breakpoint_Set
, 0);
static void if_clear_breakpoint(debugger_t
* dbgrp
)
val
= get_uint64(dbgrp
->recv_ptr
);
DBGRD( printf("clear breakpoint @ 0x%llx\n",val
););
dbgrp
->config_procp
->proc_typep
->dbgr_clear_break(dbgrp
->pspecp
, val
);
send_buffer( dbgrp
, Sim_Breakpoint_Cleared
, 0);
static void if_read_memory(debugger_t
* dbgrp
)
ptp
= dbgrp
->config_procp
->proc_typep
;
vaddr
= get_uint64(dbgrp
->recv_ptr
);
len
= get_uint32(dbgrp
->recv_ptr
+ 8);
res
= get_uint32(dbgrp
->recv_ptr
+ 12);
is_physical_addr
= (res
== 1);
DBGRD( printf("read %s memory @ 0x%llx [ 0x%x bytes]\n",
is_physical_addr
? "physical" : "virtual",
len
= ptp
->dbgr_mem_read(dbgrp
->pspecp
, vaddr
, !is_physical_addr
,
DBGRD( fprintf(stdout
, "Failed reading memory"); );
send_buffer( dbgrp
, Sim_Mem_Read_Failed_No_Mem
, 0);
send_buffer( dbgrp
, Sim_Mem_Returned
, len
);
static void if_write_memory(debugger_t
* dbgrp
)
ptp
= dbgrp
->config_procp
->proc_typep
;
vaddr
= get_uint64(dbgrp
->recv_ptr
);
len
= get_uint32(dbgrp
->recv_ptr
+ 8);
res
= get_uint32(dbgrp
->recv_ptr
+ 12);
is_physical_addr
= (res
== 1);
DBGRD( printf("write %s memory @ 0x%llx [ 0x%x bytes]\n",
is_physical_addr
? "physical" : "virtual",
len
= ptp
->dbgr_mem_write(dbgrp
->pspecp
, vaddr
, !is_physical_addr
,
dbgrp
->recv_ptr
+16, len
);
DBGRD( fprintf(stdout
, "Failed reading memory"); );
send_buffer( dbgrp
, Sim_Mem_Write_Failed_No_Mem
, 0);
send_buffer( dbgrp
, Sim_Mem_Write_OK
, 0);
static void if_clear_memory(debugger_t
* dbgrp
)
ptp
= dbgrp
->config_procp
->proc_typep
;
vaddr
= get_uint64(dbgrp
->recv_ptr
);
len
= get_uint32(dbgrp
->recv_ptr
+ 8);
res
= get_uint32(dbgrp
->recv_ptr
+ 12);
is_physical_addr
= (res
== 1);
DBGRD( printf("clear %s memory @ 0x%llx [ 0x%x bytes]\n",
is_physical_addr
? "physical" : "virtual",
len
= ptp
->dbgr_mem_clear(dbgrp
->pspecp
, vaddr
, !is_physical_addr
, len
);
DBGRD( fprintf(stdout
, "Failed clearing memory"); );
send_buffer( dbgrp
, Sim_Mem_Clear_Failed_No_Mem
, 0);
send_buffer( dbgrp
, Sim_Mem_Clear_OK
, 0);
* We enter here with the main program thread
* to wait for user interface connections.
* we never leave this function.
* The simulator closes ungracefully using exit()
* to kill its threads ...
static fd_set comm_channels
;
int tcp_attach_socket
, res
;
struct sockaddr_in tcp_server
;
pthread_sigmask(SIG_BLOCK
, &sigs
, NULL
);
skt
= socket(AF_INET
, SOCK_STREAM
, 0);
if (skt
< 0) fatal("opening stream socket");
/* enable the reuse of this socket if this process dies */
if (setsockopt(skt
,SOL_SOCKET
,SO_REUSEADDR
,(char*)&on
,sizeof(on
))<0)
fatal("turning on REUSEADDR");
tcp_server
.sin_family
= AF_INET
;
tcp_server
.sin_addr
.s_addr
= INADDR_ANY
;
tcp_server
.sin_port
= options
.accept_port
;
if (bind(skt
, (struct sockaddr
*)&tcp_server
, sizeof(tcp_server
)) < 0) {
printf("\nPort %d already in use ", options
.accept_port
);
/* user specific a port and it's not available, fatal */
if (options
.specific_port
) {
fatal("Port %d already in use, try another",
/* check if we should retry another port */
if (retry_cnt
>= options
.port_retry_max
) {
fatal("Max no of retries (%d) reached, use -P -or -p ",
printf("- trying %d", options
.accept_port
);
fatal("binding tcp stream socket");
length
= sizeof(tcp_server
);
if (getsockname(skt
, (struct sockaddr
*) &tcp_server
, &length
)==-1)
fatal("getting socket name");
PRINTF(("\nWaiting for connection on port # %d\n",
ntohs(tcp_server
.sin_port
)));
listen(skt
, MAX_CONNECTIONS
);
max_channel
= tcp_attach_socket
;
FD_SET(tcp_attach_socket
, &comm_channels
);
* Wait for a control connection
res
= select(max_channel
+1, &comm_channels
, (fd_set
*)0, (fd_set
*)0, (struct timeval
*)0 /* stall */);
if (res
<0) fatal("select");
fh
= accept(tcp_attach_socket
,(struct sockaddr
*)&from
, (int*)&fromlen
);
hp
= gethostbyaddr((char *)&from
.sin_addr
, 4, AF_INET
);
if (hp
== (struct hostent
*)0) {
froms
= inet_ntoa(from
.sin_addr
);
fprintf(stderr
,"cant resolve hostname for %s\n", froms
);;
fprintf(stderr
,"connection from %s : port %d\n", froms
, from
.sin_port
);
* Create the thread to handle this debugger
* connection. It cleans up after itself
* if anything goes wrong.
dbgrp
= Xcalloc(1, debugger_t
);
dbgrp
->state
= DS_unattached
;
pthread_mutex_init(&dbgrp
->stop_lock
, NULL
);
pthread_cond_init(&dbgrp
->stop_cv
, NULL
);
callback_register(CB_Breakpoint
, dbgrif_stop_cb
, (void *)dbgrp
);
create_thread(dbgrif
, (void*)dbgrp
, &dbgrp
->pthread_id
);
* These functions are called, not from the debugger IF thread,
* but from the simulation execution thread. It is a callback
* notification to the debugger - during simulation to load
* a new symbol table file.
void remdeb_symtab_add_callback(sym_file_t
* sym_filep
)
DBGRD( printf("load symtab %s\n",sym_filep
->namep
););
dbgr
.exec_state
= Exec_symtab_load
;
assert( dbgr
.sym_filep
== (sym_file_t
*)0);
dbgr
.sym_filep
= sym_filep
;
stop_cmd((char*)0, dbgr
.cmd_ptr
);
/* Delete a block of symbols (object file)
void remdeb_symtab_delete_callback(uint64_t symtab_id
)
DBGRD( printf("delete symtab 0x%llx\n",symtab_id
););
/* Change the offset on a block of symbols ...
void remdeb_symtab_offset_callback(uint64_t symtab_id
, uint64_t offset
, char * sectp
)
DBGRD( printf("change symtab 0x%llx : section [%s] offset 0x%llx\n",symtab_id
, sectp
? sectp
: "(NULL)", offset
););
* basic IO routines to help
static int send_buffer(debugger_t
* dbgrp
, protocol_t cmd
, int num
)
dbgrp
->send_buffer_p
[0] = num
>> 8;
dbgrp
->send_buffer_p
[1] = num
& 0xff;
dbgrp
->send_buffer_p
[2] = (unsigned char) cmd
;
res
= write(dbgrp
->socket
, dbgrp
->send_buffer_p
, 3+num
);
return (res
!= 3+num
) ? -1 : 0;
static protocol_t
recv_buffer(debugger_t
* dbgrp
, int * nrecvdp
)
len
= do_recv(dbgrp
->socket
, dbgrp
->recv_buffer_p
, 3);
if (len
!= 3) return Receive_error
;
len
= dbgrp
->recv_buffer_p
[1] + (dbgrp
->recv_buffer_p
[0]<<8); /* big endian network order */
num
= do_recv(dbgrp
->socket
, dbgrp
->recv_ptr
, len
);
if (num
!= len
) return Receive_error
;
if (nrecvdp
!= (void*)0) *nrecvdp
= num
;
return (protocol_t
)dbgrp
->recv_buffer_p
[2];
static int do_recv(int skt
, unsigned char * ptr
, int expect
)
for (idx
=0; idx
<expect
; idx
+=num
) {
num
= read(skt
, ptr
+ idx
, expect
-idx
);
static uint16_t get_uint16(uint8_t * bp
)
val
= (val
<<8) | (uint16_t)bp
[1];
static uint32_t get_uint32(uint8_t * bp
)
val
= (val
<<8) | (uint32_t)bp
[1];
val
= (val
<<8) | (uint32_t)bp
[2];
val
= (val
<<8) | (uint32_t)bp
[3];
static uint64_t get_uint64(uint8_t * bp
)
val
= (val
<<8) | (uint64_t)bp
[1];
val
= (val
<<8) | (uint64_t)bp
[2];
val
= (val
<<8) | (uint64_t)bp
[3];
val
= (val
<<8) | (uint64_t)bp
[4];
val
= (val
<<8) | (uint64_t)bp
[5];
val
= (val
<<8) | (uint64_t)bp
[6];
val
= (val
<<8) | (uint64_t)bp
[7];
static void put_uint16(uint8_t * bp
, uint16_t val
)
bp
[0] = (uint8_t)(val
>> 8);
static void put_uint32(uint8_t * bp
, uint32_t val
)
bp
[0] = (uint8_t)(val
>> 24);
bp
[1] = (uint8_t)(val
>> 16);
bp
[2] = (uint8_t)(val
>> 8);
static void put_uint64(uint8_t * bp
, uint64_t val
)
bp
[0] = (uint8_t)(val
>> 56);
bp
[1] = (uint8_t)(val
>> 48);
bp
[2] = (uint8_t)(val
>> 40);
bp
[3] = (uint8_t)(val
>> 32);
bp
[4] = (uint8_t)(val
>> 24);
bp
[5] = (uint8_t)(val
>> 16);
bp
[6] = (uint8_t)(val
>> 8);