Wolfgang Thallergcc16 merge934c3885 months agoHistory
241 lines · 5.7 KB · C++
RawDownload
/* Copyright (C) 2021-2026 Free Software Foundation, Inc.   Contributed by Oracle.    This file is part of GNU Binutils.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3, or (at your option)   any later version.    This 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 program; if not, write to the Free Software   Foundation, 51 Franklin Street - Fifth Floor, Boston,   MA 02110-1301, USA.  */ #include "config.h"#include <sys/types.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>     //  for close(); #include "util.h"#include "Data_window.h"#include "debug.h" enum{  MINBUFSIZE    = 1 << 16,  WIN_ALIGN     = 8}; Data_window::Data_window (char *file_name){  Dprintf (DEBUG_DATA_WINDOW, NTXT ("Data_window:%d %s\n"), (int) __LINE__, STR (file_name));  page_size = sysconf (_SC_PAGESIZE);  need_swap_endian = false;  opened = false;  fsize = 0;  base = NULL;  woffset = 0;  wsize = 0;  basesize = 0;  fname = dbe_strdup (file_name);  mmap_on_file = false;  use_mmap = false;#if DEBUG  if (DBE_USE_MMAP)    use_mmap = true;#endif /* DEBUG */  fd = open64 (fname, O_RDONLY);  if (fd == -1)    return;  fsize = lseek (fd, 0, SEEK_END);  if (fsize == 0)    {      close (fd);      fd = -1;      return;    }  opened = true;  if (use_mmap)    {      if (fsize != -1)	{	  base = (void*) mmap (NULL, (size_t) fsize, PROT_READ, MAP_PRIVATE, fd, 0);	  close (fd);	  fd = -1;	  if (base == MAP_FAILED)	    {	      base = NULL;	      use_mmap = false;	      return;	    }	  mmap_on_file = true;	  wsize = fsize;	}    }} void *Data_window::bind (int64_t file_offset, int64_t minSize){  Span span;  span.length = fsize - file_offset;  span.offset = file_offset;  return bind (&span, minSize);} void *Data_window::bind (Span *span, int64_t minSize){  // Do any necessary mapping to access the desired span of data  // and return a pointer to the first byte.  Dprintf (DEBUG_DATA_WINDOW, NTXT ("Data_window:bind:%d offset=%llx:%lld minSize=%lld \n"),	   (int) __LINE__, (long long) span->offset, (long long) span->length, (long long) minSize);  if (minSize == 0 || span->length < minSize)    return NULL;   if (span->offset < woffset || span->offset + minSize > woffset + wsize)    {      // Remap the window      if (span->offset + minSize > fsize)	return NULL;      int myfd = fd;      if (myfd == -1)	{	  if (fname)	    myfd = open64 (fname, O_RDONLY, 0);	  if (myfd == -1)	    return NULL;	}      bool remap_failed = true;      if (use_mmap)	{	  if (base)	    {	      munmap ((caddr_t) base, (size_t) wsize);	      base = NULL;	    }	  woffset = span->offset & ~(page_size - 1);	  wsize = page_size * ((MINBUFSIZE + page_size - 1) / page_size);	  if (span->offset + minSize > woffset + wsize)	    // Extend a window	    wsize += page_size * ((span->offset + minSize -				   woffset - wsize + page_size - 1) / page_size);	  base = (void *) mmap (0, (size_t) wsize, PROT_READ, MAP_SHARED, fd, woffset);	  if (base == MAP_FAILED)	    {	      base = NULL;	      use_mmap = false;	    }	  remap_failed = (base == NULL);	}      if (remap_failed)	{	  remap_failed = false;	  woffset = span->offset & ~(WIN_ALIGN - 1);	  wsize = minSize + (span->offset % WIN_ALIGN);	  if (wsize < MINBUFSIZE)	    wsize = MINBUFSIZE;	  if (wsize > fsize)	    wsize = fsize;	  if (basesize < wsize)	    { // Need to realloc 'base'	      free (base);	      basesize = wsize;	      base = (void *) xmalloc (basesize);	      Dprintf (DEBUG_DATA_WINDOW,		       NTXT ("Data_window:bind:%d realloc basesize=%llx woffset=%lld \n"),		       (int) __LINE__, (long long) basesize, (long long) woffset);	      if (base == NULL)		{		  basesize = 0;		  remap_failed = true;		}	    }	  if (wsize > fsize - woffset)	    wsize = fsize - woffset;	  off_t woff = (off_t) woffset;	  if (base == NULL || woff != lseek (myfd, woff, SEEK_SET)	      || wsize != read_from_file (myfd, base, wsize))	    remap_failed = true;	}      if (fd == -1)	close (myfd);      if (remap_failed)	{	  woffset = 0;	  wsize = 0;	  return NULL;	}    }  return (void *) ((char*) base + span->offset - woffset);} void *Data_window::get_data (int64_t offset, int64_t size, void *datap){  if (size <= 0)    return NULL;  void *buf = bind (offset, size);  if (buf == NULL)    return NULL;  if (datap == NULL && !mmap_on_file)    // Can be remmaped or reallocated. Need to make a copy    datap = (void *) xmalloc (size);  if (datap)    {      memcpy (datap, buf, (size_t) size);      return datap;    }  return buf;} Data_window::~Data_window (){  free (fname);  if (fd != -1)    close (fd);  if (base)    {      if (use_mmap)	munmap ((caddr_t) base, (size_t) wsize);      else	free (base);    }} int64_tData_window::get_buf_size (){  int64_t sz = MINBUFSIZE;  if (sz < basesize)    sz = basesize;  if (sz > fsize)    sz = fsize;  return sz;} int64_tData_window::copy_to_file (int f, int64_t offset, int64_t size){  long long bsz = get_buf_size ();  for (long long n = 0; n < size;)    {      long long sz = (bsz <= (size - n)) ? bsz : (size - n);      void *b = bind (offset + n, sz);      if (b == NULL)	return n;      long long len = write (f, b, sz);      if (len <= 0)	return n;      n += len;    }  return size;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t